Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving /setuid #86

Closed
wants to merge 35 commits into from
Closed

Improving /setuid #86

wants to merge 35 commits into from

Conversation

dbemiller
Copy link
Contributor

@dbemiller dbemiller commented Aug 7, 2017

This fixes two issues. I grouped them into the same PR because the code overlapped.

  1. Add metrics for counting calls to /setuid, separated by bidder.
  2. Re-sync users to audienceNetwork if we were told that their UID was 0.

The point of (2) is to circumvent around some questionable behavior from the Facebook user sync servers. Currently, they redirect to/setuid with a sentinel value of "0" if the user isn't logged into Facebook at the time. This is (at least partially) responsible for some really bad user sync rates, because prebid-server saves those 0s, considers the user to be synced, and then stops trying to sync later.

In reality, 0 is an invalid user ID... but eventually, we'd expect the user to log into Facebook, so that the audience network can sync with their real UID.

So... this PR also consolidates all UserSync Sets behind a TrySync() function, which it then implements to reject "0" IDs for audienceNetwork.

@dbemiller dbemiller changed the base branch from track-usersync-requests to gometrics-metrics August 7, 2017 19:43
@dbemiller dbemiller changed the base branch from gometrics-metrics to master August 8, 2017 13:06
@dbemiller dbemiller changed the title Resync audienceNetwork with ID = 0 Improving /setuid Aug 9, 2017
Copy link
Member

@mkendall07 mkendall07 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok to me. Not sure about needing an interface for cookie though.

//
// To get an instance of this from a request, use ParseUserSyncMapFromRequest.
// To write an instance onto a response, use SetCookieOnResponse.
type UserSyncMap interface {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need use an interface here? The type to me has to be tied to a concrete cookie as I'm not sure what else we could replace it with given the client/server interactions.

Copy link
Contributor Author

@dbemiller dbemiller Aug 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good/fair question.

I really just wanted the compiler to guarantee that all the other PBS code was going through the setter methods. I don't want the next guy who refactors an endpoint to have to worry about the fact that facebook IDs shouldn't be 0.

So... I tried to make UIDs private, and add a the setter method to the PBSCookie. But it turns out that Golang's JSON marshal & unmarshal don't work on private variables.

This was the next best thing I could come up with. UIDs can stay public, butcookieImpl will be private. The interface just exists for the public API.

Copy link
Contributor Author

@dbemiller dbemiller Aug 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the tradeoff here is...

If I have an interface, I can make the UIDs property private to the rest of the code. Without an interface, I'd leave a comment saying "// This is only public for JSON serialization. Don't use it directly. Call TrySync instead."

I generally favor using the build system rather than comments to enforce things when possible... but there is some overhead, and I've been known to take it too far. Let me know if you think it's worth removing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible instead of having the interface to create a struct that is public just for the purpose of JSON serialization? Something like what is described here (https://stackoverflow.com/questions/28035784/golang-marshal-unmarshal-json-with-both-exported-and-un-exported-fields).

Would that allow the uuids field to be private still without the need for the interface?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks like a viable option. I kinda want to compare the code side-by-side... so I'll stick it in another branch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented this in #106.

The two look pretty similar in complexity to me... but I think I give a slight edge to the concrete struct. This is how I'm thinking about it:

Concrete struct benefits:

  • nil-safety is possible (though it requires some extra branchy code).
  • nil is much clearer to mobile apps, since there's no such thing as a UserSync there.

Interface benefits:

  • No custom JSON code, so there's less room for bugs

In this case I think the confusion caused by a UserSync map on mobile requests is probably the most important part.... so gonna go with that one.

@@ -162,6 +162,8 @@ func ParsePBSRequest(r *http.Request, cache cache.Cache) (*PBSRequest, error) {
if err != nil {
return nil, fmt.Errorf("Invalid URL '%s': %v", url.Host, err)
}
} else {
pbsReq.SyncMap = NewSyncMap()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need an empty SyncMap on mobile app requests for everything to work? Cookie sync doesn’t make sense on mobile app, so having an empty sync map could be confusing.

Copy link
Contributor Author

@dbemiller dbemiller Aug 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The short answer is... I'm not sure. I definitely agree that it's confusing.

On the other hand... func (req *PBSRequest) GetUserID(BidderCode string) surfaced some interesting unit test failures. Apparently in Go any reads on a nil map are treated as if that map were empty. So pbsReq.UIDs['key'] will just return nil if UIDs is undefined, but req.SyncMap.GetUID() will cause panic. Stashing an empty SyncMap on here makes reads behave nicely.

I don't know offhand whether any of the other PBS code attempts to read cookiesyncs inside the "mobile" code branches... but as a general rule, ab object should be equally usable regardless of how its constructed.

I think this lends some extra weight to your suggestion here. If the methods are defined on a struct, then I can define how they behave on a nil. Interfaces don't give that flexibility.

@dbemiller dbemiller mentioned this pull request Aug 24, 2017
@dbemiller dbemiller closed this Aug 24, 2017
@dbemiller dbemiller deleted the resync-facebook-uid-0 branch October 13, 2017 15:01
pm-nilesh-chate pushed a commit to pm-nilesh-chate/prebid-server that referenced this pull request Feb 25, 2023
… / Ad Pod (prebid#86)

* UOE-5440: Changes for capturing Pod algorithm execution time using pbmetrics (prebid#65)

* Added function getPrometheusRegistry()

* Exported function GetPrometheusRegistry

* UOE-5440: Capturing execution time in nanoseconds for algorithms

* UOE-5440: Changes for prometheus algorithem metrics for pod using pbsmetrics

* UOE-5440: Test cases for prometheus

* UOE-5440: Added test cases

* UOE-5440: Changing buckets

* UOE-5440: changes in pbsmetrics for newly added metrics

Co-authored-by: Sachin Survase <sachin.survase@pubmatic.com>
Co-authored-by: PubMatic-OpenWrap <UOEDev@pubmatic.com>
Co-authored-by: Shriprasad <shriprasad.marathe@pubmatic.com>

* UOE-5440: Fixed the Unit test issues (prebid#72)

Fixed unit test issues 
Co-authored-by: Sachin Survase <sachin.survase@pubmatic.com>
Co-authored-by: PubMatic-OpenWrap <UOEDev@pubmatic.com>
Co-authored-by: Shriprasad <shriprasad.marathe@pubmatic.com>

* UOE-5511 Support for skadnetwork in pubmatic (prebid#73)

Co-authored-by: Isha Bharti <isha.bharti@pubmatic.com>

* Resolved merge issues

* BugID:OTT-17 First Commit

* OTT-18: moved VideoAuction to selector pattern. This  required for mocking PBS response (prebid#76)

Co-authored-by: Shriprasad <shriprasad.marathe@pubmatic.com>

* OTT-24: Basic support for sorting the deal bids in forming the final ad pod response

* OTT-24: Added changes around prebid#1503 (Proposal for Prebid Server)

* OTT-27, OTT-32 Supporting Deal Prioritization for CTV

* UOE-5616: Support wiid in pubmatic (prebid#77)

Co-authored-by: Isha Bharti <isha.bharti@pubmatic.com>

* OTT-29 Fixing Skip Dedup Map Issue

* OTT-29 Fixing Skip Dedup Map Issue

* OTT-29 Adding Video Duration in hb_pb_cat_dur key

* OTT-29 Adding Video Duration in hb_pb_cat_dur key
OTT-29 Fixing Skip Dedup Map Issue

* UOE-5741: adding omitempty for ExtImpPrebid fields

* UOE-5741: adding omitempty for ExtImpPrebid fields

* OTT-9 Adding Duration in hb_pb_cat_dur field

* OTT-9 Adding Duration in hb_pb_cat_dur field

* OTT-45: Added logger and Prometheus metrics to capture bid.id collisions (prebid#84)

* OTT-45: Added logger and Prometheus metrics to capture bid.id collisions
Co-authored-by: Shriprasad <shriprasad.marathe@pubmatic.com>

* OTT-9 Removed duplicate import

* OTT-45: corrected comment

* OTT-9: Reverted with master changes. This changes are not required for OTT-9

Co-authored-by: Sachin Survase <sachin.survase@pubmatic.com>
Co-authored-by: PubMatic-OpenWrap <UOEDev@pubmatic.com>
Co-authored-by: Shriprasad <shriprasad.marathe@pubmatic.com>
Co-authored-by: Isha Bharti <isha.bharti@pubmatic.com>
Co-authored-by: Viral Vala <viral.vala@pubmatic.com>
Co-authored-by: shalmali-patil <shalmali.patil@pubmatic.com>
StarWindMoonCloud pushed a commit to ParticleMedia/prebid-server that referenced this pull request Jun 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants